﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace InnovTech.Wpf.Command
{
    // <summary>
    /// This class gives some simplified contructors to create <typeparamref name="DelegateCommand<Object>"/>.
    /// All arguments can only be assigned by the creation once.
    /// </summary>
    public class DelegateCommand : DelegateCommand<Object>
    {
        #region static fields
        /// <summary>
        /// An empty parameter list to be used to change an Action object to an Action<Object> instance with a Lambda expression
        /// </summary>
        private static readonly object[] EmptyParamList;

        #endregion static fields

        #region constructors

        /// <summary>
        /// the static constructor to initialize all static fields used by this object
        /// </summary>
        static DelegateCommand()
        {
            EmptyParamList = new object[0];
        }

        /// <summary>
        /// Create a DelegateCommand instance according with the given Action&lt;Object&gt;, Predicate&lt;Object&gt; objects and the auto requery indicator.
        /// </summary>
        /// <param name="executeMethod">an Action&lt;Object&gt; object which should be executed when the Execute method is called</param>
        /// <param name="canExecuteMethod">a Predicate&lt;Object&gt; object which should be executed when the CanExecute method is called. default is null</param>
        /// <param name="isAutomaticRequeryDisabled">a boolean which indicates whether the CanExecut method shouldnot be executed when any input event is triggered. default is false</param>
        /// <example>
        /// ICommand cmd = new DelegateCommand( o => do something, x => false, true);
        /// </example>
        public DelegateCommand(Action<Object> executeMethod, Predicate<Object> canExecuteMethod = null, bool isAutomaticRequeryDisabled = false)
            : base(executeMethod, canExecuteMethod, isAutomaticRequeryDisabled)
        {
        }

        /// <summary>
        /// Create a DelegateCommand instance according with the given Action&lt;Object&gt; and the auto requery indicator.
        /// </summary>
        /// <param name="executeMethod">an Action&lt;Object&gt; object which should be executed when the Execute method is called</param>
        /// <param name="isAutomaticRequeryDisabled">a boolean which indicates whether the CanExecut method shouldnot be executed when any input event is triggered.</param>
        /// <example>
        /// ICommand cmd = new DelegateCommand( o => do something, true);
        /// </example>
        public DelegateCommand(Action<Object> executeMethod, bool isAutomaticRequeryDisabled)
            : this(executeMethod, null, isAutomaticRequeryDisabled)
        {
        }


        /// <summary>
        /// Create a DelegateCommand instance according with the given Action, Predicate&lt;Object&gt; objects and the auto requery indicator.
        /// </summary>
        /// <param name="executeMethod">an Action object which should be executed when the Execute method is called</param>
        /// <param name="canExecuteMethod">a Predicate&lt;Object&gt; object which should be executed when the CanExecute method is called. default is null</param>
        /// <param name="isAutomaticRequeryDisabled">a boolean which indicates whether the CanExecut method shouldnot be executed when any input event is triggered. default is false</param>
        /// <example>
        /// ICommand cmd = new DelegateCommand( () => do something, o => false, true);
        /// </example>
        public DelegateCommand(Action executeMethod, Predicate<Object> canExecuteMethod = null, bool isAutomaticRequeryDisabled = false)
            : this( //use the lambda expression and the DynamicInvoke method of the Action Object to change an Action to an Action<Object>
                    o => executeMethod.DynamicInvoke(EmptyParamList),
                    canExecuteMethod,
                    isAutomaticRequeryDisabled)
        {
        }

        /// <summary>
        /// Create a <typeparamref name="DelegateCommand"/> instance according with the given Action object and the auto requery indicator.
        /// </summary>
        /// <param name="executeMethod">an Action object which should be executed when the Execute method is called</param>
        /// <param name="isAutomaticRequeryDisabled">a boolean which indicates whether the CanExecut method shouldnot be executed when any input event is triggered.</param>
        /// <example>
        /// ICommand cmd = new DelegateCommand( () => do something, true);
        /// </example>
        public DelegateCommand(Action executeMethod, bool isAutomaticRequeryDisabled)
            : this(o => executeMethod.DynamicInvoke(EmptyParamList),
                   null,
                   isAutomaticRequeryDisabled)
        {
        }

        #endregion constructors
    }
}
